<script setup lang="ts">
import dayjs from 'dayjs'
import { useIndicatorDataCurve } from './composable'
import { useChartToolboxDataView } from '@/mixins/MixinChartToolboxDataView'
import { STORAGE_MODES } from '@/enum/modules/indicator'
import { STORAGE_MODES_OPTIONS } from '@/mixins/StatisticalIndicators/MixinStatisticalIndicators'
import type { DatePickType } from 'element-plus'
import UpdateDataModal from './UpdateDataModal.vue'
import { useChartTooltipTheme } from '@/mixins/MixinChartTooltipTheme'
import { DEFAULT_OPTION } from '@/components/view-chart-line/index'

const props = withDefaults(defineProps<{
  indicatorNumber: string
  title?: string
  initialTimeType?: STORAGE_MODES
  initialStartTime?: string
  initialEndTime?: string
}>(), {
  title: '实时数据折线图',
  initialTimeType: STORAGE_MODES.NOW,
  initialStartTime: dayjs().subtract(24, 'hour').format('YYYY-MM-DD HH:mm'),
  initialEndTime: dayjs().format('YYYY-MM-DD HH:mm'),
})

const emits = defineEmits<{
  (e: 'close'): void
}>()

const [visible, setVisible] = useState(false)

const updateDataModalRef = ref<InstanceType<typeof UpdateDataModal>>()

const timeTypeOptions = computed(() => {
  return STORAGE_MODES_OPTIONS.filter(v => v.value !== STORAGE_MODES.NOW)
})
const timeType = ref(props.initialTimeType)
const startTime = ref(props.initialStartTime)
const endTime = ref(props.initialEndTime)

const isLive = computed(() => unref(timeType) === STORAGE_MODES.NOW)
const isHour = computed(() => unref(timeType) === STORAGE_MODES.HOUR)
const pickerType = computed(() => {
  return ({
    [STORAGE_MODES.NOW]: 'datetime',
    [STORAGE_MODES.FIFTEEN_MINUTES]: 'datetime',
    [STORAGE_MODES.HOUR]: 'datetime',
    [STORAGE_MODES.DAY]: 'date',
    [STORAGE_MODES.MONTH]: 'month',
    [STORAGE_MODES.YEAR]: 'year',
  })[timeType.value] as DatePickType
})
const pickerFormat = computed(() => {
  return ({
    [STORAGE_MODES.NOW]: 'YYYY-MM-DD HH:mm',
    [STORAGE_MODES.FIFTEEN_MINUTES]: 'YYYY-MM-DD HH:mm',
    [STORAGE_MODES.HOUR]: 'YYYY-MM-DD HH',
    [STORAGE_MODES.DAY]: 'YYYY-MM-DD',
    [STORAGE_MODES.MONTH]: 'YYYY-MM',
    [STORAGE_MODES.YEAR]: 'YYYY',
  })[timeType.value]
})

const {
  loading,
  data,
  indicator,
  queryIndicatorDataByTimeType,
} = useIndicatorDataCurve()

const { dataView } = useChartToolboxDataView({
  optionToContent: (opt: any, g: (d: any) => string | HTMLElement) => {
    const source = opt.dataset[0]?.source || []
    const times = source[0] ?? []
    const values = source[1] ?? []
    const data = [
      ...times.map((v: any, i: number) => [v, values[i]] as [string, number]),
    ]
    return g(data)
  },
  dataViewFirstCellName: '时间',
})
const tooltipTheme = useChartTooltipTheme()
const lineOption = computed(() => {
  return {
    legend: {
      show: false,
    },
    tooltip: {
      ...DEFAULT_OPTION.tooltip,
      ...tooltipTheme,
    },
    xAxis: {
      type: 'category',
    },
    yAxis: {
      type: 'value',
    },
    grid: {
      top: '40px',
      left: '20px',
      right: '20px',
      bottom: '60px',
      containLabel: true,
    },
    toolbox: {
      show: true,
      feature: {
        dataView: unref(dataView),
        magicType: {
          type: ['line', 'bar'],
          title: {
            line: '切换为折线图',
            bar: '切换为柱状图',
          },
        },
      },
    },
    dataZoom: [
      { type: 'slider', left: '120px', right: '120px' },
      { type: 'inside' },
    ],
    series: [{
      symbolSize: 5,
      smooth: false,
      lineStyle: {
        width: 2,
      },
    }],
  }
})
const lineData = computed(() => unref(data))

const current = shallowRef<any>({
  indicatorNumber: props.indicatorNumber,
  indicatorName: '',
  unit: '',
  indicatorCode: '',
  time: '',
  value: null,
})

function format(v: string) {
  return dayjs(v).format(
    unref(isLive)
      ? 'YYYY-MM-DD HH:mm:00'
      : unref(pickerFormat),
  )
}

async function clickSearch() {
  if (new Date(unref(startTime)).getTime() > new Date(unref(endTime)).getTime())
    return ElMessage.error('结束时间不能小于开始时间')

  await queryIndicatorDataByTimeType({
    timeType: timeType.value,
    indicatorNumber: props.indicatorNumber,
    startTime: format(startTime.value),
    endTime: format(endTime.value),
  })
}

async function clickChart(e: any) {
  if (unref(timeType) !== STORAGE_MODES.NOW)
    return
  const [time, value] = e.data ?? []
  if (time) {
    current.value = {
      ...unref(indicator),
      time,
      value,
    }
    await nextTick()
    updateDataModalRef.value?.open()
  }
}

async function showModal() {
  timeType.value = props.initialTimeType
  startTime.value = props.initialStartTime
  endTime.value = props.initialEndTime
  await nextTick()
  clickSearch()
  setVisible(true)
}

// 时间从日切换到小时，格式化有bug 如 2023-10-01 不能正常显示 2023-10-01 00
watch(
  () => unref(timeType),
  (val: STORAGE_MODES) => {
    if (val === STORAGE_MODES.HOUR) {
      startTime.value = dayjs(unref(startTime)).format('YYYY-MM-DD 00')
      endTime.value = dayjs(unref(endTime)).format('YYYY-MM-DD 00')
    }
  },
)

watch(
  () => unref(visible),
  (val: boolean) => {
    if (!val) {
      emits('close')
    }
  },
)

defineExpose({
  showModal,
})
</script>

<template>
  <FullscreenModal v-model="visible">
    <div v-if="visible" class="h-full w-full flex flex-col gap-4">
      <ElPageHeader class="flex-shrink-0" title="返回" @back="visible = false">
        <template #content>
          <span>{{ title }}</span>
        </template>
      </ElPageHeader>
      <ElForm class="flex-shrink-0" inline>
        <ElFormItem v-if="!isLive" label="时间类型">
          <ElSelect v-model="timeType">
            <ElOption
              v-for="item in timeTypeOptions"
              :key="item.value" :label="item.label" :value="item.value"
            />
          </ElSelect>
        </ElFormItem>
        <ElFormItem label="时间">
          <ElDatePicker
            v-model="startTime"
            :popper-class="isHour ? 'is-hour-in-hide-panel' : ''"
            :type="pickerType"
            :format="pickerFormat"
            :value-format="pickerFormat"
            :clearable="false"
          />
          <span class="fs-14 text-placeholder mx-3">至</span>
          <ElDatePicker
            v-model="endTime"
            :popper-class="isHour ? 'is-hour-in-hide-panel' : ''"
            :type="pickerType"
            :format="pickerFormat"
            :value-format="pickerFormat"
            :clearable="false"
          />
        </ElFormItem>
        <ElFormItem>
          <SearchButton @click="clickSearch" />
        </ElFormItem>
      </ElForm>
      <div class="fs-14 text-regular flex flex-wrap items-center line-height-normal">
        <span class="text-placeholder">指标编码：</span> <code>{{ indicator.indicatorNumber }}</code>
        <span class="text-placeholder ml-10">指标名称：</span> {{ indicator.indicatorName }}
        <span class="text-placeholder ml-10">单位：</span> {{ indicator.unit }}
        <span class="text-placeholder ml-10">测点点位号：</span> <code>{{ indicator.indicatorCode }}</code>
      </div>
      <div v-loading="loading" element-loading-custom-class="global-loading" class="flex-1 overflow-auto">
        <ViewChartLine
          autoresize
          :mark-line="[]"
          :option="lineOption"
          :dataset="{
            source: lineData,
          }"
          :is-area-shadow="false"
          :is-line-shadow="false"
          @click="clickChart"
        />
      </div>
      <!-- 修改实时数据对话框 -->
      <UpdateDataModal
        v-if="current && current.time"
        ref="updateDataModalRef"
        v-model="current"
        @save-success="clickSearch"
      />
    </div>
  </FullscreenModal>
</template>

<style lang="scss">
.is-hour-in-hide-panel {
  .el-time-panel {
    .el-time-spinner__wrapper {
      width: 100%;
      &:last-child {
        display: none;
      }
    }
  }
}
</style>
